Java 學習筆記 04 – 資料型別轉換


Posted by vickyh1315 on 2024-04-09

接續第二篇資料型態提到,這樣宣告 Java 編譯會報錯

int a = 10;
float b = 10.0f;
a = b; // Error

原因是在於當宣告時 Java 已經對 a 跟 b 分配好記憶體跟定義好範圍(32bits, -2^31 ~ 2^31-1 / 32bits, -2^128 ~ +2^127),規範禁止的原因是考慮可能發生下列這些:

  1. 範圍不同:要將範圍大的浮點數賦值給範圍小的整數 ,假設浮點數的值已經超出整數定義範圍,會導致「溢出」的情況,造成結果失準
  2. 精度損失:整數不存在小數點後面的位數,如果將 1.512 賦值給整數,.512 就會被截掉,就不同於原本的值
  3. 表示方式不同:整數是以固定位數表示數值,例如 10 是二位數,100 是三位數,浮點數是使用 IEEE-754 規範

但總會遇到要運算像 1.5 * 2 這種情形,因為 Java 運算只能在全部型別相同才能進行,所以內部存在型別的轉換機制(Casting),有

  1. 自動型別轉換(隱式轉換)
  2. 強制型別轉換(顯式轉換)

兩種類型。

自動型別轉換(隱式轉換)

根據資料型別能存放的範圍,最左邊最小,最右邊最大
byte → short → int → long → float → double
也就是說,箭頭左邊的型別可以指定給右邊的型別。

回顧一開始的情境,因為 a 是 int,b 是 float,所以當 b 賦值給 a,編譯會報錯。
但是當 a 賦值給 a,轉換的條件就成立了,這時候 b 會等於 10。

運算式轉換

Java 運算只在型別相同才能進行,如果運算式存在不同型別,只要他做得到,就會以最大的型別為基準,提升比較小的型別,再開始它的運算:

int intA = 3;
double doubleB = 1.5 * intA; // 提升 intA 型別至 double
System.out.print(doubleB); // 4.5

數值轉換部分,除了十進制,二進制、八進制、十六進制表示也可以轉換

int eight = 010; // 8
// hexadecimal 由 0~9, A~F 表示
int sixteen = 0x10; // 16
int fifteen = 0XF; // 15

字元轉換也是除了一般表示,轉役序列('\n', '\', '\r')、Unicode('\u5b57')也可以互相轉換、進行邏輯運算。

char ch = 'a';
char ch2 = '\u0022'; // '""'
ch = 65; // 'A'
ch++; // 'A'
ch; // 'B'
++ch; // 'C'
ch+5; // 72
(int)ch; // 67
ch >= 48 && ch <= 57; // 判斷 ch 是不是字母

整數/浮點數與字串組合

int num1 = 1;
float num2 = num1 * 10.0f;
String printNum1 = "this is " + num2;

強制型別轉換(顯式轉換)

有時還是必須要將較大資料類別,指定給較小資料類別,使用自動型別轉換,Java 就會報錯說它做不到,這時就要手動進行強制型別轉換。
第二篇提到 long a = 15000000000Lfloat b = 5.0F 的宣告方式,就是使用強制型別轉換

int num = 2147483648; // Error,超出 int 範圍
long num = 2147483648; // Error,雖然型別是 long,但 Java 預設型態 int,轉換前就會報錯
long num = 2147483648L; // Success

double num2 = 3.5; // Success
float num2 = 3.5F; // Success

另種方式是在常值前用()指定轉換的型別

int num2 = (int)3.5; // Success,得到 3

雖說強制轉換行得通,但要注意範圍,否則轉換還是會發生值轉換前後不一致的情形

// 會失準的情況
int num = (int)2147483648L; // Success,型態順利從 long 再轉回 int,但超出 int 範圍,所以得到值是 -2147483648
byte num = (byte)250; // Success,型態可轉 byte,但超出範圍,得到值是 -6

#java







Related Posts

Day02 : 在 React 中可能會碰到的 JavaScript 觀念

Day02 : 在 React 中可能會碰到的 JavaScript 觀念

【Day05】實戰開始 - 區塊分割

【Day05】實戰開始 - 區塊分割

立即呼叫函式表達式(IIFE)

立即呼叫函式表達式(IIFE)


Comments